﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="VehicleTransactionManager.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the  interface.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Business
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.Linq;
    using Common;
    using Data.Interfaces;
    using Entities;
    using Interfaces;

    using Microsoft.Practices.ServiceLocation;

    /// <summary>
    /// Defines the <seealso cref="Hisaab.Business.VehicleTransactionManager"/> type.
    /// </summary>
    public class VehicleTransactionManager : IVehicleTransactionManager
    {
        /// <summary>
        /// VehicleTransaction repository
        /// </summary>
        private readonly IVehicleTransactionRepository _vehicleTransactionRepository;

        /// <summary>
        /// Transaction Manager
        /// </summary>
        private readonly ITransactionRepository _transactionRepository;

        /// <summary>
        /// Initializes a new instance of the <see cref="VehicleTransactionManager"/> class.
        /// </summary>
        public VehicleTransactionManager()
            : this(
                ServiceLocator.Current.GetInstance<IVehicleTransactionRepository>(),
                ServiceLocator.Current.GetInstance<IVehicleRepository>(),
                ServiceLocator.Current.GetInstance<ITransactionRepository>())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="VehicleTransactionManager"/> class.
        /// </summary>
        /// <param name="vehicleTransactionRepository">The vehicle transaction repository.</param>
        /// <param name="vehicleRepository">The vehicle repository.</param>
        /// <param name="transactionRepository">The transaction repository.</param>
        public VehicleTransactionManager(IVehicleTransactionRepository vehicleTransactionRepository, IVehicleRepository vehicleRepository, ITransactionRepository transactionRepository)
        {
            Contract.Requires<ArgumentNullException>(vehicleTransactionRepository != null);
            Contract.Requires<ArgumentNullException>(vehicleRepository != null);
            Contract.Requires<ArgumentNullException>(transactionRepository != null);
            _vehicleTransactionRepository = vehicleTransactionRepository;
            _transactionRepository = transactionRepository;
        }

        /// <summary>
        /// Gets the filtered.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <param name="pageNo">The page no.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <returns>List of filtered items</returns>
        public IEnumerable<VehicleTransaction> List(VehicleTransaction filter, int? pageNo, int? pageSize)
        {
            return _vehicleTransactionRepository.Query(filter.Map<VehicleTransaction, Data.Entities.VehicleTransaction>(), pageNo, pageSize)
                .ToList()
                .Select(x => x.Map<Data.Entities.VehicleTransaction, VehicleTransaction>());
        }

        /// <summary>
        /// Adds the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns>Id of vehicle transaction added</returns>
        public int Add(VehicleTransaction entity)
        {
            decimal totalAmount = CalculateTransactionTotal(entity);
            entity.TransactionId = _transactionRepository.Add(new Data.Entities.Transaction { Account = entity.Account, Amount = totalAmount, Date = DateTime.Now, Title = GetFuelEntryTitle(entity) });
            return _vehicleTransactionRepository.Add(entity.Map<VehicleTransaction, Data.Entities.VehicleTransaction>());
        }

        /// <summary>
        /// Updates the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        public void Update(VehicleTransaction entity)
        {
            _vehicleTransactionRepository.Update(entity.Map<VehicleTransaction, Data.Entities.VehicleTransaction>());
        }

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        public void Delete(VehicleTransaction entity)
        {
            _vehicleTransactionRepository.Delete(entity.Map<VehicleTransaction, Data.Entities.VehicleTransaction>());
        }

        /// <summary>
        /// Gets the by id.
        /// </summary>
        /// <param name="id">The vehicle transaction id.</param>
        /// <returns>Vehicle transaction matching id</returns>
        public VehicleTransaction GetById(int id)
        {
            return _vehicleTransactionRepository.FindById(id).Map<Data.Entities.VehicleTransaction, VehicleTransaction>();
        }

        /// <summary>
        /// Calculates the total.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns>Total of all items in the vehicle transaction</returns>
        private decimal CalculateTransactionTotal(VehicleTransaction entity)
        {
            return (entity.Fuel.HasValue ? entity.Fuel.Value : 0) +
                   (entity.Oil.HasValue ? entity.Oil.Value : 0) +
                   (entity.Service.HasValue ? entity.Service.Value : 0) +
                   (entity.Tires.HasValue ? entity.Tires.Value : 0);
        }

        /// <summary>
        /// Gets the fuel entry title.
        /// </summary>
        /// <param name="entity">The vehicle transaction entity.</param>
        /// <returns>Name of fuel transaction</returns>
        private string GetFuelEntryTitle(VehicleTransaction entity)
        {
            return "Transaction for vehicle" + entity.VehicleId;
        }
    }
}